<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>热门景点访问量条形图竞速</title>
    <!-- 引入 ECharts -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.2/dist/echarts.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        
        .container {
            width: 100%;
            max-width: 1200px;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 16px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
            backdrop-filter: blur(10px);
            padding: 30px;
        }
        
        .header {
            text-align: center;
            margin-bottom: 30px;
        }
        
        .header h1 {
            font-size: 28px;
            color: #2c3e50;
            margin-bottom: 10px;
            font-weight: 600;
        }
        
        .header p {
            color: #7f8c8d;
            font-size: 16px;
        }
        
        .chart-container {
            width: 100%;
            height: 600px;
            position: relative;
        }
        
        .controls {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-top: 20px;
            flex-wrap: wrap;
        }
        
        .control-btn {
            padding: 10px 20px;
            background: linear-gradient(135deg, #3498db, #2980b9);
            color: white;
            border: none;
            border-radius: 30px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3);
        }
        
        .control-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4);
        }
        
        .control-btn:active {
            transform: translateY(0);
        }
        
        .control-btn.playing {
            background: linear-gradient(135deg, #e74c3c, #c0392b);
            box-shadow: 0 4px 15px rgba(231, 76, 60, 0.3);
        }
        
        .speed-control {
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        .speed-control label {
            color: #2c3e50;
            font-size: 14px;
            font-weight: 500;
        }
        
        .speed-control input {
            width: 120px;
        }
        
        .time-display {
            text-align: center;
            margin-top: 15px;
            font-size: 24px;
            font-weight: bold;
            color: #3498db;
        }
        
        /* 响应式设计 */
        @media (max-width: 768px) {
            .container {
                padding: 20px;
            }
            
            .header h1 {
                font-size: 24px;
            }
            
            .chart-container {
                height: 400px;
            }
            
            .controls {
                flex-direction: column;
                align-items: center;
            }
        }
        
        /* 加载动画 */
        .loader {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            display: none;
        }
        
        .loader.show {
            display: block;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>热门景点访问量动态排名</h1>
            <p>基于月访问量数据的可视化展示</p>
        </div>
        <div class="chart-container">
            <div id="barRaceChart"></div>
            <div class="loader show">
                <svg width="40" height="40" viewBox="0 0 40 40">
                    <circle cx="20" cy="20" r="18" fill="none" stroke="#3498db" stroke-width="3" stroke-dasharray="80" stroke-dashoffset="80">
                        <animate attributeName="stroke-dashoffset" from="80" to="0" dur="1s" repeatCount="indefinite"></animate>
                    </circle>
                </svg>
            </div>
        </div>
        <div class="time-display" id="timeDisplay">2024年1月</div>
        <div class="controls">
            <button class="control-btn" id="playPauseBtn">开始</button>
            <div class="speed-control">
                <label for="speedSlider">播放速度:</label>
                <input type="range" id="speedSlider" min="0.5" max="3" step="0.5" value="1">
            </div>
            <button class="control-btn" id="resetBtn">重置</button>
        </div>
    </div>

    <script>
        // 模拟数据 - 热门景点月访问量
        const generateData = () => {
            const months = ['2024年1月', '2024年2月', '2024年3月', '2024年4月', '2024年5月', '2024年6月',
                           '2024年7月', '2024年8月', '2024年9月', '2024年10月', '2024年11月', '2024年12月'];
            
            const spots = [
                { name: '长城', base: 100000, growth: 0.08 },
                { name: '故宫博物院', base: 90000, growth: 0.06 },
                { name: '天坛公园', base: 75000, growth: 0.05 },
                { name: '颐和园', base: 85000, growth: 0.07 },
                { name: '西湖', base: 95000, growth: 0.09 },
                { name: '黄山风景区', base: 65000, growth: 0.12 },
                { name: '九寨沟', base: 60000, growth: 0.15 },
                { name: '张家界', base: 55000, growth: 0.11 },
                { name: '兵马俑', base: 80000, growth: 0.04 },
                { name: '布达拉宫', base: 50000, growth: 0.10 }
            ];
            
            const data = {};
            months.forEach((month, index) => {
                data[month] = spots.map(spot => {
                    // 季节性波动 + 基础增长 + 随机波动
                    const seasonalFactor = 1 + 0.3 * Math.sin(index / 12 * Math.PI * 2);
                    const monthFactor = 1 + spot.growth * index;
                    const randomFactor = 0.8 + Math.random() * 0.4;
                    const value = Math.round(spot.base * monthFactor * seasonalFactor * randomFactor);
                    return { name: spot.name, value: value };
                }).sort((a, b) => b.value - a.value);
            });
            
            return { months, data };
        };
        
        // 颜色配置
        const colors = [
            '#FF6B6B', '#4ECDC4', '#45B7D1', '#F9CA24', '#6C5CE7',
            '#A29BFE', '#FD79A8', '#FDCB6E', '#00B894', '#E17055'
        ];
        
        // 初始化图表
        let chart, currentMonthIndex = 0, timer = null, isPlaying = false;
        let speed = 1; // 默认速度
        const { months, data } = generateData();
        
        function initChart() {
            chart = echarts.init(document.getElementById('barRaceChart'));
            
            updateChart(0);
            
            // 窗口大小改变时重新调整图表
            window.addEventListener('resize', () => {
                chart.resize();
            });
            
            // 隐藏加载动画
            document.querySelector('.loader').classList.remove('show');
        }
        
        function updateChart(monthIndex) {
            const month = months[monthIndex];
            const monthData = data[month];
            
            // 只显示前8个数据
            const displayData = monthData.slice(0, 8);
            
            const option = {
                backgroundColor: 'transparent',
                textStyle: {
                    fontFamily: 'Microsoft YaHei, PingFang SC, sans-serif'
                },
                grid: {
                    top: 20,
                    right: 100,
                    bottom: 40,
                    left: 100
                },
                xAxis: {
                    type: 'value',
                    axisLine: {
                        show: false
                    },
                    axisTick: {
                        show: false
                    },
                    axisLabel: {
                        color: '#666',
                        fontSize: 12,
                        formatter: value => {
                            if (value >= 10000) {
                                return (value / 10000).toFixed(1) + '万';
                            }
                            return value;
                        }
                    },
                    splitLine: {
                        lineStyle: {
                            color: '#f0f0f0',
                            type: 'dashed'
                        }
                    }
                },
                yAxis: {
                    type: 'category',
                    data: displayData.map(item => item.name),
                    axisLine: {
                        show: false
                    },
                    axisTick: {
                        show: false
                    },
                    axisLabel: {
                        color: '#333',
                        fontSize: 14,
                        fontWeight: 'bold'
                    }
                },
                series: [{
                    type: 'bar',
                    data: displayData.map((item, index) => ({
                        value: item.value,
                        itemStyle: {
                            color: colors[index % colors.length],
                            borderRadius: [0, 4, 4, 0]
                        },
                        label: {
                            show: true,
                            position: 'right',
                            color: '#666',
                            fontSize: 12,
                            fontWeight: 'bold',
                            formatter: params => {
                                if (params.value >= 10000) {
                                    return (params.value / 10000).toFixed(1) + '万';
                                }
                                return params.value;
                            }
                        }
                    })),
                    barWidth: '60%',
                    emphasis: {
                        itemStyle: {
                            shadowBlur: 10,
                            shadowColor: 'rgba(0, 0, 0, 0.3)'
                        }
                    }
                }],
                animationDuration: 750,
                animationEasing: 'cubicOut'
            };
            
            chart.setOption(option);
            document.getElementById('timeDisplay').textContent = month;
        }
        
        function playAnimation() {
            if (timer) return;
            
            timer = setInterval(() => {
                currentMonthIndex++;
                if (currentMonthIndex >= months.length) {
                    currentMonthIndex = 0;
                }
                updateChart(currentMonthIndex);
            }, 2000 / speed);
        }
        
        function pauseAnimation() {
            if (timer) {
                clearInterval(timer);
                timer = null;
            }
        }
        
        function resetAnimation() {
            pauseAnimation();
            currentMonthIndex = 0;
            updateChart(currentMonthIndex);
            isPlaying = false;
            document.getElementById('playPauseBtn').textContent = '开始';
            document.getElementById('playPauseBtn').classList.remove('playing');
        }
        
        // 事件监听
        document.getElementById('playPauseBtn').addEventListener('click', () => {
            isPlaying = !isPlaying;
            if (isPlaying) {
                playAnimation();
                document.getElementById('playPauseBtn').textContent = '暂停';
                document.getElementById('playPauseBtn').classList.add('playing');
            } else {
                pauseAnimation();
                document.getElementById('playPauseBtn').textContent = '开始';
                document.getElementById('playPauseBtn').classList.remove('playing');
            }
        });
        
        document.getElementById('resetBtn').addEventListener('click', resetAnimation);
        
        document.getElementById('speedSlider').addEventListener('input', (e) => {
            speed = parseFloat(e.target.value);
            if (isPlaying) {
                pauseAnimation();
                playAnimation();
            }
        });
        
        // 页面加载完成后初始化图表
        window.addEventListener('load', initChart);
    </script>
</body>
</html>